package org.kjtc.balanceController;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.kjtc.balanceEntity.BalanceBill;
import org.kjtc.balanceEntity.BalanceBillDetail;
import org.kjtc.balanceEntity.BalanceBillMeterDetail;
import org.kjtc.balanceEntity.ChargingRecord;
import org.kjtc.balanceEntity.MeterRecord;
import org.kjtc.balanceEntity.PowerFactor;
import org.kjtc.balanceEntity.StationStandard;
import org.kjtc.balanceService.CostManageService;
import org.kjtc.balanceService.PowerFactorService;
import org.kjtc.balanceService.StationStandardService;
import org.kjtc.controller.BaseController;
import org.kjtc.util.DoubleUtil;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class BalanceBillController extends BaseController {

	@Resource(name = "costManageService")
	private CostManageService costManageService;
	
	@Resource(name = "powerFactorService")
	private PowerFactorService powerFactorService;
	
	@Resource(name = "stationStandardService")
	private StationStandardService stationStandardService;

	@RequestMapping(value = "/searchMeterInfo")
	@ResponseBody
	public Map<String, Object> searchMeterInfo(MeterRecord meterRecord, String defaultBalanceDay, String fixPrices, String fixRatios){

		double fixPrice = Double.valueOf(fixPrices);
		double fixRatio = Double.valueOf(fixRatios);
		Map<String, Object> map = new HashMap<String, Object>();
		logger.info(this.getUesrInfo().getUserName() + "(" + this.getUesrInfo().getUserID() + ")：" + "电表信息查询开始");
		List<MeterRecord> meterRecordList = null;
		List<ChargingRecord> chargingRecordList = null;
		List<PowerFactor> powerFactorList = null;
		List<BalanceBillDetail> balanceBillList = new ArrayList<BalanceBillDetail>();
		List<BalanceBillMeterDetail> balanceBillMeterDetailList = new ArrayList<BalanceBillMeterDetail>();
		List<StationStandard> stationStandardList = null;
		try {
			int count = costManageService.getBillMeterRecordCount(meterRecord);
			if (count > 0) {
				ChargingRecord chargingRecord = new ChargingRecord();
				
				chargingRecord.setStartChargingDate(meterRecord.getBalanceMonth().concat(defaultBalanceDay));
				powerFactorList = powerFactorService.getPowerFactor(null);
				chargingRecordList = costManageService.getChargingStationKWH(chargingRecord);
				meterRecordList = costManageService.getBillMeterRecord(meterRecord);
				stationStandardList = stationStandardService.getStationStandardPrice();
				meterRecord = new MeterRecord();
				
				for(MeterRecord meterRecords: meterRecordList){
					BalanceBillMeterDetail balanceBillMeterDetail = new BalanceBillMeterDetail();
					if(meterRecord.getChargingStationID() != null && meterRecord.getChargingStationID().equals(meterRecords.getChargingStationID()) && meterRecord.getMeterCode() != null && meterRecord.getMeterCode().equals(meterRecords.getMeterCode())) {
						balanceBillMeterDetail.setChargingStationID(meterRecords.getChargingStationID());
						balanceBillMeterDetail.setChargingStationName(meterRecords.getChargingStationName());
						balanceBillMeterDetail.setCheckMeterCode(meterRecords.getMeterCode());
						balanceBillMeterDetail.setCheckMeterRate(meterRecords.getMeterRate());
						balanceBillMeterDetail.setTotalMeterLastNo(meterRecord.getPowerTotal());
						balanceBillMeterDetail.setTotalMeterThisNo(meterRecords.getPowerTotal());
						balanceBillMeterDetail.setSharpMeterLastNo(meterRecord.getPowerAiguille());
						balanceBillMeterDetail.setSharpMeterThisNo(meterRecords.getPowerAiguille());
						balanceBillMeterDetail.setPeakMeterLastNo(meterRecord.getPowerPeak());
						balanceBillMeterDetail.setPeakMeterThisNo(meterRecords.getPowerPeak());
						balanceBillMeterDetail.setFlatMeterLastNo(meterRecord.getPowerFlat());
						balanceBillMeterDetail.setFlatMeterThisNo(meterRecords.getPowerFlat());
						balanceBillMeterDetail.setValleyMeterLastNo(meterRecord.getPowerGrain());
						balanceBillMeterDetail.setValleyMeterThisNo(meterRecords.getPowerGrain());
						balanceBillMeterDetail.setIdleTotalLastNo(meterRecord.getIdleTotal());
						balanceBillMeterDetail.setIdleTotalThisNo(meterRecords.getIdleTotal());
						balanceBillMeterDetail.setLastCheckDate(meterRecord.getMeterDate());
						balanceBillMeterDetail.setThisCheckDate(meterRecords.getMeterDate());
						balanceBillMeterDetailList.add(balanceBillMeterDetail);
						balanceBillMeterDetail = null;
					}
					meterRecord = meterRecords;
				}
				BalanceBillDetail balanceBillDetail = new BalanceBillDetail();
				for(int i = 0; i < balanceBillMeterDetailList.size(); i++) {
					if(i != balanceBillMeterDetailList.size() - 1 && balanceBillMeterDetailList.get(i+1).getChargingStationID().equals(balanceBillMeterDetailList.get(i).getChargingStationID())) {
						balanceBillDetail.setChargingStationID(balanceBillMeterDetailList.get(i).getChargingStationID());
						balanceBillDetail.setTotalActiveKWH(DoubleUtil.add(DoubleUtil.mul(DoubleUtil.sub(balanceBillMeterDetailList.get(i).getTotalMeterThisNo(), balanceBillMeterDetailList.get(i).getTotalMeterLastNo()), (double)balanceBillMeterDetailList.get(i).getCheckMeterRate()), balanceBillDetail.getTotalActiveKWH()));
						balanceBillDetail.setSharpActiveKWH(DoubleUtil.add(DoubleUtil.mul(DoubleUtil.sub(balanceBillMeterDetailList.get(i).getSharpMeterThisNo(), balanceBillMeterDetailList.get(i).getSharpMeterLastNo()), (double)balanceBillMeterDetailList.get(i).getCheckMeterRate()), balanceBillDetail.getSharpActiveKWH()));
						balanceBillDetail.setPeakActiveKWH(DoubleUtil.add(DoubleUtil.mul(DoubleUtil.sub(balanceBillMeterDetailList.get(i).getPeakMeterThisNo(), balanceBillMeterDetailList.get(i).getPeakMeterLastNo()), (double)balanceBillMeterDetailList.get(i).getCheckMeterRate()), balanceBillDetail.getPeakActiveKWH()));
						balanceBillDetail.setFlatActiveKWH(DoubleUtil.add(DoubleUtil.mul(DoubleUtil.sub(balanceBillMeterDetailList.get(i).getFlatMeterThisNo(), balanceBillMeterDetailList.get(i).getFlatMeterLastNo()), (double)balanceBillMeterDetailList.get(i).getCheckMeterRate()), balanceBillDetail.getFlatActiveKWH()));
						balanceBillDetail.setValleyActiveKWH(DoubleUtil.add(DoubleUtil.mul(DoubleUtil.sub(balanceBillMeterDetailList.get(i).getValleyMeterThisNo(), balanceBillMeterDetailList.get(i).getValleyMeterLastNo()), (double)balanceBillMeterDetailList.get(i).getCheckMeterRate()), balanceBillDetail.getValleyActiveKWH()));
						balanceBillDetail.setTotalIdleKWH(DoubleUtil.add(DoubleUtil.mul(DoubleUtil.sub(balanceBillMeterDetailList.get(i).getIdleTotalThisNo(), balanceBillMeterDetailList.get(i).getIdleTotalLastNo()), (double)balanceBillMeterDetailList.get(i).getCheckMeterRate()), balanceBillDetail.getTotalIdleKWH()));
					} else {
						balanceBillDetail.setChargingStationID(balanceBillMeterDetailList.get(i).getChargingStationID());
						balanceBillDetail.setCheckMeterLastTime(balanceBillMeterDetailList.get(i).getLastCheckDate());
						balanceBillDetail.setCheckMeterThisTime(balanceBillMeterDetailList.get(i).getThisCheckDate());
						//计算充电量
						balanceBillDetail.setTotalActiveKWH(DoubleUtil.add(DoubleUtil.mul(DoubleUtil.sub(balanceBillMeterDetailList.get(i).getTotalMeterThisNo(), balanceBillMeterDetailList.get(i).getTotalMeterLastNo()), (double)balanceBillMeterDetailList.get(i).getCheckMeterRate()), balanceBillDetail.getTotalActiveKWH()));
						balanceBillDetail.setSharpActiveKWH(DoubleUtil.add(DoubleUtil.mul(DoubleUtil.sub(balanceBillMeterDetailList.get(i).getSharpMeterThisNo(), balanceBillMeterDetailList.get(i).getSharpMeterLastNo()), (double)balanceBillMeterDetailList.get(i).getCheckMeterRate()), balanceBillDetail.getSharpActiveKWH()));
						balanceBillDetail.setPeakActiveKWH(DoubleUtil.add(DoubleUtil.mul(DoubleUtil.sub(balanceBillMeterDetailList.get(i).getPeakMeterThisNo(), balanceBillMeterDetailList.get(i).getPeakMeterLastNo()), (double)balanceBillMeterDetailList.get(i).getCheckMeterRate()), balanceBillDetail.getPeakActiveKWH()));
						balanceBillDetail.setFlatActiveKWH(DoubleUtil.add(DoubleUtil.mul(DoubleUtil.sub(balanceBillMeterDetailList.get(i).getFlatMeterThisNo(), balanceBillMeterDetailList.get(i).getFlatMeterLastNo()), (double)balanceBillMeterDetailList.get(i).getCheckMeterRate()), balanceBillDetail.getFlatActiveKWH()));
						balanceBillDetail.setValleyActiveKWH(DoubleUtil.add(DoubleUtil.mul(DoubleUtil.sub(balanceBillMeterDetailList.get(i).getValleyMeterThisNo(), balanceBillMeterDetailList.get(i).getValleyMeterLastNo()), (double)balanceBillMeterDetailList.get(i).getCheckMeterRate()), balanceBillDetail.getValleyActiveKWH()));
						balanceBillDetail.setTotalIdleKWH(DoubleUtil.add(DoubleUtil.mul(DoubleUtil.sub(balanceBillMeterDetailList.get(i).getIdleTotalThisNo(), balanceBillMeterDetailList.get(i).getIdleTotalLastNo()), (double)balanceBillMeterDetailList.get(i).getCheckMeterRate()), balanceBillDetail.getTotalIdleKWH()));
						//计算尖峰平谷占比
						balanceBillDetail.setSharpProportion(Double.toString(DoubleUtil.mul(DoubleUtil.divide(balanceBillDetail.getSharpActiveKWH(), balanceBillDetail.getTotalActiveKWH(), 4), (double)100)).concat("%"));
						balanceBillDetail.setPeakProportion(Double.toString(DoubleUtil.mul(DoubleUtil.divide(balanceBillDetail.getPeakActiveKWH(), balanceBillDetail.getTotalActiveKWH(), 4), (double)100)).concat("%"));
						balanceBillDetail.setFlatProportion(Double.toString(DoubleUtil.mul(DoubleUtil.divide(balanceBillDetail.getFlatActiveKWH(), balanceBillDetail.getTotalActiveKWH(), 4), (double)100)).concat("%"));
						balanceBillDetail.setValleyProportion(Double.toString(DoubleUtil.mul(DoubleUtil.divide(balanceBillDetail.getValleyActiveKWH(), balanceBillDetail.getTotalActiveKWH(), 4), (double)100)).concat("%"));
						//获取场站计算标准
						String factorStandard = "";
						String powerFactor = "";
						double sharpPrice = 0;
						double peakPrice = 0;
						double flatPrice = 0;
						double valleyPrice = 0;
						double addUnitPrice = 0;
						for(StationStandard stationStandard: stationStandardList) {
							if(balanceBillDetail.getChargingStationID().equals(stationStandard.getChargingStationID())) {
								factorStandard = stationStandard.getFactorStandard();
								powerFactor = stationStandard.getPowerFactor();
								sharpPrice = stationStandard.getSharpChargingPrice();
								peakPrice = stationStandard.getPeakChargingPrice();
								flatPrice = stationStandard.getFlatChargingPrice();
								valleyPrice = stationStandard.getValleyChargingPrice();
								addUnitPrice = stationStandard.getAddUnitPrice();
								break;
							}
						}
						//计算向分公司收缴电费
						for(ChargingRecord chargingRecords: chargingRecordList) {
							if(chargingRecords.getChargingStationID().equals(balanceBillMeterDetailList.get(i).getChargingStationID())) {
								balanceBillDetail.setTotalChargingKWH(chargingRecords.getTotalChargingKWH());
								double costSubtotal = DoubleUtil.mul(DoubleUtil.mul(fixPrice, fixRatio), balanceBillDetail.getTotalChargingKWH());
								balanceBillDetail.setCostSubtotal(round(costSubtotal));
								break;
							}
						}
						//计算单站系数
						if(balanceBillDetail.getTotalChargingKWH() > 0) {
							balanceBillDetail.setStationRatio(DoubleUtil.divide(balanceBillDetail.getTotalActiveKWH(), balanceBillDetail.getTotalChargingKWH(), 4));
						} else {
							balanceBillDetail.setStationRatio(0);
						}
						//计算电力公司支付电费
						for(int j = 0; j < powerFactorList.size(); j++) {
							double powerRatio = 0.0;
							if(j == powerFactorList.size() - 1) {
								if(powerFactor.equals("0")){
									powerRatio = powerFactorList.get(j).getElectricityOne();
								} else if(powerFactor.equals("1")) {
									powerRatio = powerFactorList.get(j).getElectricityTwo();
								} else {
									powerRatio = powerFactorList.get(j).getElectricityThree();
								}
								powerRatio = DoubleUtil.divide(powerRatio, (double)100);
								double sharpCharge = DoubleUtil.mul(sharpPrice, balanceBillDetail.getSharpActiveKWH());
								double peakCharge = DoubleUtil.mul(peakPrice, balanceBillDetail.getPeakActiveKWH());
								double flatCharge = DoubleUtil.mul(flatPrice, balanceBillDetail.getFlatActiveKWH());
								double valleyCharge = DoubleUtil.mul(valleyPrice, balanceBillDetail.getValleyActiveKWH());
								double totalCharge = DoubleUtil.add(DoubleUtil.add(DoubleUtil.add(sharpCharge, peakCharge), flatCharge), valleyCharge);
								//参与功率因数调整电费
								double adjustCharge = DoubleUtil.sub(totalCharge, DoubleUtil.mul(balanceBillDetail.getTotalActiveKWH(), addUnitPrice));
								if(factorStandard.equals("2") && adjustCharge < 0) {
									adjustCharge = 0;
								}
								double payElectricCharge = DoubleUtil.add(totalCharge, DoubleUtil.mul(adjustCharge, powerRatio));
								balanceBillDetail.setPayElectricCharge(round(payElectricCharge));
							} else {
								//无功/有功
								if(DoubleUtil.divide(balanceBillDetail.getTotalIdleKWH(), balanceBillDetail.getTotalActiveKWH(), 4) >= powerFactorList.get(j).getPowerMin() && DoubleUtil.divide(balanceBillDetail.getTotalIdleKWH(), balanceBillDetail.getTotalActiveKWH(), 4) <= powerFactorList.get(j).getPowerMax()) {
									if(powerFactor.equals("0")){
										powerRatio = powerFactorList.get(j).getElectricityOne();
									} else if(powerFactor.equals("1")) {
										powerRatio = powerFactorList.get(j).getElectricityTwo();
									} else {
										powerRatio = powerFactorList.get(j).getElectricityThree();
									}
									powerRatio = DoubleUtil.divide(powerRatio, (double)100, 4);
									double sharpCharge = DoubleUtil.mul(sharpPrice, balanceBillDetail.getSharpActiveKWH());
									double peakCharge = DoubleUtil.mul(peakPrice, balanceBillDetail.getPeakActiveKWH());
									double flatCharge = DoubleUtil.mul(flatPrice, balanceBillDetail.getFlatActiveKWH());
									double valleyCharge = DoubleUtil.mul(valleyPrice, balanceBillDetail.getValleyActiveKWH());
									double totalCharge = DoubleUtil.add(DoubleUtil.add(DoubleUtil.add(sharpCharge, peakCharge), flatCharge), valleyCharge);
									//参与功率因数调整电费
									double adjustCharge = DoubleUtil.sub(totalCharge, DoubleUtil.mul(balanceBillDetail.getTotalActiveKWH(), addUnitPrice));
									if(factorStandard.equals("1") && adjustCharge < 0) {
										adjustCharge = 0;
									}
									double payElectricCharge = DoubleUtil.add(totalCharge, DoubleUtil.mul(adjustCharge, powerRatio));
									balanceBillDetail.setPayElectricCharge(round(payElectricCharge));
									break;
								}
							}
						}
						//计算差值、比值
						balanceBillDetail.setDifference(DoubleUtil.sub(balanceBillDetail.getCostSubtotal(), balanceBillDetail.getPayElectricCharge()));
						balanceBillDetail.setRatio(DoubleUtil.divide(balanceBillDetail.getDifference(), balanceBillDetail.getTotalActiveKWH(), 4));
						balanceBillList.add(balanceBillDetail);
						balanceBillDetail = null;
						if(i != balanceBillMeterDetailList.size() - 1) {
							balanceBillDetail = new BalanceBillDetail();
						}
					}
				}
				chargingRecord = null;
			}
			this.setSessionAttribute("meterInfoList", balanceBillList);
			this.setSessionAttribute("stationKWHInfoList", balanceBillMeterDetailList);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(this.getUesrInfo().getUserName() + "(" + this.getUesrInfo().getUserID() + ")：" + "电表信息查询异常:" + e.getMessage());
		}
		logger.info(this.getUesrInfo().getUserName() + "(" + this.getUesrInfo().getUserID() + ")：" + "电表信息查询结束");
		map.put("meterInfoList", balanceBillList);
		map.put("stationKWHInfoList", balanceBillMeterDetailList);
		meterRecord = null;
		balanceBillList = null;
		balanceBillMeterDetailList = null;
		return map;
	}
	
	public double round(double value) {
		BigDecimal b = new BigDecimal(Double.toString(value));
		return b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/saveBillInfo")
	@ResponseBody
	public Map<String, Object> saveMeterInfo(BalanceBill balanceBill){

		Map<String, Object> map = new HashMap<String, Object>();
		logger.info(this.getUesrInfo().getUserName() + "(" + this.getUesrInfo().getUserID() + ")：" + "电力结算单保存开始");
		
		List<BalanceBillDetail> balanceBillDetailList = null;
		List<BalanceBillMeterDetail> balanceBillMeterDetailList = null;
		balanceBillDetailList = (List<BalanceBillDetail>) this.getSessionAttribute("meterInfoList");
		balanceBillMeterDetailList = (List<BalanceBillMeterDetail>) this.getSessionAttribute("stationKWHInfoList");
		balanceBill.setCreateUser(this.getUesr().getUserID());
		balanceBill.setUpdateUser(this.getUesr().getUserID());
		double totalPayElectricCharge = 0.0;
		double sumTotalChargingKWH = 0.0;
		double totalCostSubtotal = 0.0;
		double totalDifference = 0.0;
		for(int i = 0; i < balanceBillDetailList.size(); i++) {
			balanceBillDetailList.get(i).setBalanceBillName(balanceBill.getBalanceBillName());
			balanceBillDetailList.get(i).setCreateUser(this.getUesr().getUserID());
			balanceBillDetailList.get(i).setUpdateUser(this.getUesr().getUserID());
			totalPayElectricCharge = DoubleUtil.add(balanceBillDetailList.get(i).getPayElectricCharge(), totalPayElectricCharge);
			sumTotalChargingKWH = DoubleUtil.add(balanceBillDetailList.get(i).getTotalChargingKWH(), sumTotalChargingKWH);
			totalCostSubtotal = DoubleUtil.add(balanceBillDetailList.get(i).getCostSubtotal(), totalCostSubtotal);
			totalDifference = DoubleUtil.add(balanceBillDetailList.get(i).getDifference(), totalDifference);
		}
		for(int i = 0; i < balanceBillMeterDetailList.size(); i++) {
			balanceBillMeterDetailList.get(i).setBalanceBillName(balanceBill.getBalanceBillName());
			balanceBillMeterDetailList.get(i).setCreateUser(this.getUesr().getUserID());
			balanceBillMeterDetailList.get(i).setUpdateUser(this.getUesr().getUserID());
		}
		balanceBill.setTotalPayElectricCharge(totalPayElectricCharge);
		balanceBill.setSumTotalChargingKWH(sumTotalChargingKWH);
		balanceBill.setTotalCostSubtotal(totalCostSubtotal);
		balanceBill.setTotalDifference(totalDifference);
		int count1 = 0;
		int count2 = 0;
		int count3 = 0;
		try {
			count1 = costManageService.saveBalanceBill(balanceBill);
			count2 = costManageService.saveBalanceBillDetail(balanceBillDetailList);
			count3 = costManageService.saveBalanceBillMeterDetail(balanceBillMeterDetailList);
			if (count1 > 0 && count2 > 0 && count3 > 0) {
				map.put("result", "Success");
				logger.info(this.getUesrInfo().getUserName() + "(" + this.getUesrInfo().getUserID() + ")：" + "电力结算单保存成功");
			} else {
				map.put("result", "DataError");
			}
		} catch (DuplicateKeyException ex){
			String[] error = ex.getCause().getMessage().split("'");
			if ("BalanceBillName".equals(error[3].trim())) {
				map.put("result", "BalanceBillNameExist");
			}
		} catch (Exception e) {
			logger.error(this.getUesrInfo().getUserName() + "(" + this.getUesrInfo().getUserID() + ")：" + "电力结算单保存异常:" + e.getMessage());
			map.put("result", "Error");
		}
		logger.info(this.getUesrInfo().getUserName() + "(" + this.getUesrInfo().getUserID() + ")：" + "电力结算单保存结束");

		return map;
	}
}
